package com.sec.etech.employeesync.sapquery.service;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sec.etech.employeesync.config.ConfigManager;
import com.sec.etech.employeesync.enums.SyncType;
import com.sec.etech.employeesync.sapquery.factory.QueryStrategyFactory;
import com.sec.etech.employeesync.sapquery.strategy.QueryStrategy;
import com.sec.etech.employeesync.service.EmployeeDataSyncService;
import com.sec.etech.employeesync.service.EmployeeSyncService;
import com.sec.etech.employeesync.util.EducationalExperienceHandler;
import com.sec.etech.employeesync.util.EmployeeFilterHandler;
import com.sec.etech.employeesync.util.MainWorkExperienceHandler;
import com.sec.etech.ism.model.IsmAppSetting;
import com.sec.etech.ism.model.IsmServiceDef;
import com.sec.etech.ism.service.IsmAppSettingService;
import com.sec.etech.ism.service.IsmServiceDefService;
import com.sec.etech.ism.util.SapSignatureUtil;
import com.sec.etech.org.service.EtechUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.openbpm.base.api.exception.BusinessException;
import org.openbpm.org.api.model.IUser;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@Service
public class SapEmployeeQueryService {

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    private final ReentrantLock lock = new ReentrantLock();

    private final ConfigManager configManager;
    private final IsmAppSettingService ismAppSettingService;
    private final IsmServiceDefService ismServiceDefService;
    private final EmployeeDataSyncService employeeDataSyncService;
    private final EmployeeSyncService employeeSyncService;
    private final MainWorkExperienceHandler mainWorkExperienceHandler;
    private final EducationalExperienceHandler educationalExperienceHandler;
    private final EmployeeFilterHandler employeeFilterHandler;

    public SapEmployeeQueryService(IsmAppSettingService ismAppSettingService,
                                   IsmServiceDefService ismServiceDefService,
                                   EmployeeDataSyncService employeeDataSyncService,
                                   EmployeeSyncService employeeSyncService,
                                   ConfigManager configManager,
                                   MainWorkExperienceHandler mainWorkExperienceHandler,
                                   EducationalExperienceHandler educationalExperienceHandler,
                                   EmployeeFilterHandler employeeFilterHandler) {
        this.ismAppSettingService = ismAppSettingService;
        this.ismServiceDefService = ismServiceDefService;
        this.employeeDataSyncService = employeeDataSyncService;
        this.employeeSyncService = employeeSyncService;
        this.configManager = configManager;
        this.mainWorkExperienceHandler = mainWorkExperienceHandler;
        this.educationalExperienceHandler = educationalExperienceHandler;
        this.employeeFilterHandler = employeeFilterHandler;
    }

//    public String querySapEmployee(String sysCode, String serviceCode, JSONObject businessParams) {
//        boolean acquiredLock = false; // 用于跟踪是否获取到锁
//
//        try {
//            if (!lock.tryLock()) {
//                log.error("当前已有请求正在处理，请稍后再试");
//                return "当前正在处理其他同事的请求，请稍后再试";
//            }
//
//            acquiredLock = true;
//
//            log.info("businessParams===>{}", businessParams);
//
//            configManager.initAllConfig();
//            mainWorkExperienceHandler.initCompanyMap();
//            mainWorkExperienceHandler.initAllExperiences();
//            employeeFilterHandler.initConfirmMap();
//            employeeFilterHandler.initOriginList();
//
//            SyncType syncType = getSyncType(businessParams.getString("type"));
//            if (syncType == null) {
//                throw new BusinessException("type不能为空");
//            }
//
//            QueryStrategy strategy = QueryStrategyFactory.getStrategy(businessParams.getString("option"));
//            List<JSONObject> sapParamsList = strategy.buildSapParams(businessParams);
//
//            IsmAppSetting appSetting = ismAppSettingService.getByCode(sysCode);
//            IsmServiceDef serviceDef = ismServiceDefService.getByCode(serviceCode);
//
//            String url = appSetting.getAppAddress();
//            String appKey = appSetting.getAppKey2();
//
//            log.info("SAP请求地址==>{}", url);
//            log.info("SAP-appKey==>{}", appKey);
//
//            int timeout = JSON.parseObject(serviceDef.getParams()).getInteger("timeout");
//
//            String currentUserId = businessParams.getString("currentUserId");
//            IUser iUser = EtechUserUtil.getUserById(currentUserId);
//
//            CompletableFuture.allOf(sapParamsList.stream()
//                            .map(sapParams -> CompletableFuture.runAsync(() -> {
//                                try {
//                                    JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
//                                    String body = JSON.toJSONString(bodyObj);
//
//                                    long startTime = System.currentTimeMillis();
//                                    String result = HttpUtil.post(url, body, timeout * 60 * 1000);
//
//                                    log.info("SAP请求体==>{}", body);
//                                    log.info("SAP查询参数==>{}", sapParams);
//                                    log.info("SAP系统{}接口耗时：{}ms。", "调用SAP接口批量集团员工信息", System.currentTimeMillis() - startTime);
//                                    log.info("SAP返回值==>{}", result);
//
//                                    JSONObject resultObj = JSON.parseObject(result);
//                                    Boolean success = resultObj.getBoolean("success");
//                                    if (success) {
//                                        String companyCode = syncType == SyncType.COMPANY ? sapParams.getString("I_WERKS") : "";
//                                        employeeSyncService.syncEmployeeData(resultObj, syncType, companyCode, iUser);
//                                    }
//                                } catch (Exception e) {
//                                    log.error("查询SAP报错: ", e);
//                                }
//                            }, threadPoolTaskExecutor))
//                            .toArray(CompletableFuture[]::new))
//                    .join();
//
//            return "success";
//        } catch (BusinessException e) {
//            log.error("业务异常: ", e);
//            return "错误：" + e.getMessage();
//        } catch (Exception e) {
//            log.error("未知错误: ", e);
//            return "未知错误，请联系管理员";
//        } finally {
//            if (acquiredLock) {
//                lock.unlock();
//            }
//        }
//    }

    public JSONObject querySapEmployee(String sysCode, String serviceCode, JSONObject businessParams) {
        boolean acquiredLock = false; // 用于跟踪是否获取到锁
        JSONObject result = new JSONObject();
        List<String> errorMessages = new CopyOnWriteArrayList<>(); // 用于存储错误信息
        AtomicLong totalSapTime = new AtomicLong(0);

        try {
            if (!lock.tryLock()) {
                log.error("当前已有请求正在处理，请稍后再试");
                result.put("flag", false);
                result.put("msg", "当前正在处理其他同事的请求，请稍后再试");
                return result;
            }

            acquiredLock = true;

            long startTimeALL = System.currentTimeMillis();

            log.info("businessParams===>{}", businessParams);

            this.init();

            SyncType syncType = getSyncType(businessParams.getString("type"));
            if (syncType == null) {
                throw new BusinessException("type不能为空");
            }

            QueryStrategy strategy = QueryStrategyFactory.getStrategy(businessParams.getString("option"));
            List<JSONObject> sapParamsList = strategy.buildSapParams(businessParams);
            log.info("sapParamsList大小===>{}", sapParamsList.size());
//            log.info("sapParamsList===>{}", sapParamsList);

            IsmAppSetting appSetting = ismAppSettingService.getByCode(sysCode);
            IsmServiceDef serviceDef = ismServiceDefService.getByCode(serviceCode);

            String url = appSetting.getAppAddress();
            String appKey = appSetting.getAppKey2();

            log.info("SAP请求地址==>{}", url);
            log.info("SAP-appKey==>{}", appKey);

            int timeout = JSON.parseObject(serviceDef.getParams()).getInteger("timeout");

            String currentUserId = businessParams.getString("currentUserId");
            IUser iUser = EtechUserUtil.getUserById(currentUserId);

            for (JSONObject sapParams : sapParamsList) {
                try {
                    JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
                    String body = JSON.toJSONString(bodyObj);

                    long startTime = System.currentTimeMillis();
                    String resultStr = HttpUtil.post(url, body, timeout * 60 * 1000);
                    long sapCallTime = System.currentTimeMillis() - startTime;
                    // 累加SAP接口调用时间
                    totalSapTime.addAndGet(sapCallTime);

                    log.info("SAP请求体==>{}", body);
                    log.info("SAP查询参数==>{}", sapParams);
//                            log.info("SAP返回值==>{}", resultStr);

                    JSONObject resultObj = JSON.parseObject(resultStr);
                    Boolean success = resultObj.getBoolean("success");
                    if (success) {
                        String companyCode = syncType == SyncType.COMPANY ? sapParams.getString("I_WERKS") : "";
                        log.info("companyCode==>{}", companyCode);

                        if (syncType == SyncType.COMPANY) {
                            JSONArray etResult = resultObj.getJSONObject("data").getJSONArray("ET_RESULT");
                            boolean flag = etResult.stream()
                                    .anyMatch(o -> {
                                        JSONObject object = (JSONObject) o;
                                        String bukrs = object.getString("BUKRS");
                                        return !companyCode.equals(bukrs);
                                    });
                            if (flag) {
                                log.info("SAP人员返回值与查询参数不一致,{}", companyCode);
                                throw new BusinessException("SAP人员返回值与查询参数不一致," + companyCode);
                            }
                        }

                        employeeSyncService.syncEmployeeData(resultObj, syncType, companyCode, iUser);
                    } else {
                        errorMessages.add(String.format("查询SAP失败，日志：%s", body));
                    }
                } catch (Exception e) {
                    log.error("查询SAP报错: ", e);
                    String body = "";
                    try {
                        JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
                        body = JSON.toJSONString(bodyObj);
                    } catch (Exception ex) {
                        log.error("异常处理中生成SAP请求体报错:{} ", ex.getMessage());
                    }

                    errorMessages.add(String.format("对接SAP失败: %s，日志：%s", e.getMessage(), body));
                }
            }

//            CompletableFuture<Void> allTasks = CompletableFuture.allOf(sapParamsList.stream()
//                    .map(sapParams -> CompletableFuture.runAsync(() -> {
//
//                    }, threadPoolTaskExecutor))
//                    .toArray(CompletableFuture[]::new));
//
//            allTasks.join();

            // 检查是否有任何错误
            if (errorMessages.isEmpty()) {
                result.put("flag", "success");
                result.put("msg", "同步成功");
            } else {
                result.put("flag", false);
                result.put("msg", String.join("；", errorMessages));
            }

            log.info("SAP接口调用总耗时：{}ms。", totalSapTime.get());
            log.info("SAP同步总体耗时：{}ms。", System.currentTimeMillis() - startTimeALL);
            log.info("同步结果=====>{}", result.toJSONString());

            return result;
        } catch (BusinessException e) {
            log.error("业务异常: ", e);
            result.put("flag", false);
            result.put("msg", "错误：" + e.getMessage());
            return result;
        } catch (Exception e) {
            log.error("未知错误: ", e);
            result.put("flag", false);
            result.put("msg", "未知错误，请联系管理员：" + e.getMessage());
            return result;
        } finally {
            if (acquiredLock) {
                lock.unlock();
            }
        }
    }

    private void init() {
        CompletableFuture<Void> allTasks = CompletableFuture.allOf(
                CompletableFuture.runAsync(configManager::initAllConfig),
                CompletableFuture.runAsync(mainWorkExperienceHandler::initCompanyMap),
                CompletableFuture.runAsync(mainWorkExperienceHandler::initAllExperiences),
                CompletableFuture.runAsync(educationalExperienceHandler::initAllExperiences),
//                CompletableFuture.runAsync(employeeFilterHandler::initConfirmMap),
                CompletableFuture.runAsync(employeeFilterHandler::initOriginList));
        allTasks.join();
    }

    private SyncType getSyncType(String type) {
        switch (type) {
            case "SINGLE":
                return SyncType.SINGLE;
            case "COMPANY":
            case "FULL":
                return SyncType.COMPANY;
            default:
                return null;
        }
    }

    public Boolean checkSapEmployeeByAccount(String account, String companyCode) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        QueryStrategy strategy = QueryStrategyFactory.getStrategy("account");

        JSONObject businessParams = new JSONObject();
        businessParams.put("account", account);
        businessParams.put("code", companyCode);
        List<JSONObject> sapParamsList = strategy.buildSapParams(businessParams);

        String sysCode = "sap_all_employee";
        String serviceCode = "querySapEmployeeByWerks";

        IsmAppSetting appSetting = ismAppSettingService.getByCode(sysCode);
        IsmServiceDef serviceDef = ismServiceDefService.getByCode(serviceCode);

        String appKey = appSetting.getAppKey2();
        String url = appSetting.getAppAddress();

        int timeout = JSON.parseObject(serviceDef.getParams()).getInteger("timeout");

        JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParamsList.get(0), appKey);
        String body = JSON.toJSONString(bodyObj);

        long startTime = System.currentTimeMillis();
        String result = HttpUtil.post(url, body, timeout * 60 * 1000);

        log.info("SAP请求地址==>{}", url);
        log.info("SAP-appKey==>{}", appKey);
        log.info("SAP请求体==>{}", body);
        log.info("SAP查询参数==>{}", sapParamsList);
        log.info("SAP系统{}接口耗时：{}ms。", "调用SAP接口单个员工信息", System.currentTimeMillis() - startTime);
        log.info("SAP返回值==>{}", result);

        JSONObject resultObj = JSON.parseObject(result);
        JSONArray jsonArray = resultObj.getJSONObject("data").getJSONArray("ET_RESULT");

        return jsonArray.isEmpty();
    }
}
